﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace ArgusPCLib.Threading.Collections
{
	public interface ISynchronizedCollection<T> : ISynchronizedEnumerable<T>, ICollection<T>
	{
		T[] ToArray();
	}

	public abstract class SynchronizedCollectionBase<T> : SynchronizedEnumerableBase<T>, ISynchronizedCollection<T>
	{
		public SynchronizedCollectionBase()
			: base() { }

		public SynchronizedCollectionBase(object syncRoot)
			: base(syncRoot) { }

		public T[] ToArray()
		{
			lock (this.SyncRoot)
			{
				T[] array = new T[this.CountGetCore()];
				this.CopyToCore(array, 0);
				return array;
			}
		}

		protected abstract bool IsReadOnlyGetCore();
		bool ICollection<T>.IsReadOnly { get { return this.IsReadOnlyGetCore(); } }

		protected abstract int CountGetCore();
		int ICollection<T>.Count { get { return this.CountGetCore(); } }

		protected abstract bool RemoveCore(T item);
		bool ICollection<T>.Remove(T item)
		{
			lock (this.SyncRoot) { return this.RemoveCore(item); }
		}

		protected abstract void CopyToCore(T[] array, int index);
		void ICollection<T>.CopyTo(T[] array, int index)
		{
			lock (this.SyncRoot) { this.CopyToCore(array, index); }
		}

		protected abstract bool ContainsCore(T item);
		bool ICollection<T>.Contains(T item)
		{
			lock (this.SyncRoot) { return this.ContainsCore(item); }
		}

		protected abstract void ClearCore();
		void ICollection<T>.Clear()
		{
			lock (this.SyncRoot) { this.ClearCore(); }
		}

		protected abstract void AddCore(T item);
		void ICollection<T>.Add(T item)
		{
			lock (this.SyncRoot) { this.AddCore(item); }
		}
	}
}
